<template>
    <div class="app-container">
        <div class="header_container">
            任务计划
            <div class="header_right" v-if="token && token != ''">
                <el-dropdown>
                    <span class="el-dropdown-link">
                        欢迎您:&nbsp;&nbsp;&nbsp;{{ token }}
                        <i class="el-icon-arrow-down el-icon--right"></i>
                    </span>
                    <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item>
                            <span @click="loginOut">
                                退出登录
                            </span>
                        </el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
            </div>
        </div>
        <div ref="gantt" style="height:calc(100vh - 50px)"></div>
        <!-- <button @click="handleGetData">获取数据</button> -->
        <!-- <button @click="handleClearData">清除数据</button> -->
    </div>
</template>
<script>
import gantt from 'dhtmlx-gantt'  // 引入模块
//import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
import 'dhtmlx-gantt/codebase/skins/dhtmlxgantt_terrace.css' //皮肤
import 'dhtmlx-gantt/codebase/locale/locale_cn'  // 本地化
import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js' //任务条悬浮提示
import { Message } from 'element-ui';
import { taskList, taskAdd, taskEdit, taskDel, linkList, linkAdd, linkEdit, linkDel } from '@/api/index.js'
import localStroage from '@/utils/localStroage.js'
const { setStroage, getStroage } = localStroage;

function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}


export default {
    name: 'gantt',
    data() {
        return {
            optionType: '新建',
            tasks: {
                data: [],
                links: [],
            },
            token: "",
        }
    },
    methods: {
        //开始时间-结束时间参数
        DateDifference: function (strDateStart, strDateEnd) {
            var begintime_ms = Date.parse(new Date(strDateStart.replace(/-/g, '/'))) //begintime 为开始时间
            var endtime_ms = Date.parse(new Date(strDateEnd.replace(/-/g, '/')))   // endtime 为结束时间
            var date3 = endtime_ms - begintime_ms //时间差的毫秒数
            var days = Math.floor(date3 / (24 * 3600 * 1000))
            return days
        },
        // 获取数据
        handleGetData() {
            var allData = gantt.serialize(); // 获取当前所有数据
            console.log(allData)
            // 通过接口将所有数据持久化
            // 例如：使用 fetch 或 axios 发送 POST 请求将数据提交至后端
        },
        // 清除数据
        handleClearData() {
            window.localStorage.clear()
            window.location.reload()
        },
        refreshData() {
            gantt.refreshData();
            gantt.refresh();
        },
         // 退出登录
         loginOut() {
            window.localStorage.clear();
            window.location.reload();
        },
    },
    created() {
        // this.token = getStroage('token');
        // if (!this.token) {
        //     this.$router.push('/login')
        // }
    },
    mounted() {
        const _this = this;

        // function hasPriority(parent, priority) {
        //     if (gantt.getTask(parent).priority == priority)
        //         return true;

        //     var child = gantt.getChildren(parent);
        //     for (var i = 0; i < child.length; i++) {
        //         if (hasPriority(child[i], priority))
        //             return true;
        //     }
        //     return false;
        // }

        // gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
        //     console.log(task)
        //     if (hasPriority(id, '')) {
        //         return true;
        //     }
        //     return false;
        // });

        // 任务视图单进度条右侧描述
        // gantt.templates.rightside_text = function (start, end, task) {
        //     return "ID: #" + task.id;
        // };

        // 任务视图单进度条左侧描述
        gantt.templates.leftside_text = function (start, end, task) {
            return task.duration + " days";
        };

        // 点击表头可排序
        gantt.config.sort = true;

        // 静态背景
        // gantt.config.static_background = true;

        // 固定头部
        // gantt.config.static_header = true;
        /*
        * 冒烟：fcca02    单元：fec0dc     回归：62ddd4   阶段：d1a6ff
        * */
        //设置图表区域的日期坐标最大值 var date = new Date(dateString.replace(/-/,"/"))
        //  gantt.config.start_date = new Date("2020-04-08".replace(/-/,"/")) ;
        // gantt.config.end_date = new Date("2020-04-18".replace(/-/,"/")) ; //结束时间需要+1天
        //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
        // gantt.config.autosize = true // 设置高度之后会冲突
        //只读模式
        gantt.config.readonly = false // 是否可以设置
        //是否显示左侧树表格
        gantt.config.show_grid = true // 是否显示树结构
        //表格列设置 设置之后不可以添加编辑
        // gantt.config.columns = [
        //     { name: 'text', label: '阶段名字', tree: true, width: '160' },
        //     {
        //         name: 'duration', label: '时长', align: 'center', template: function (obj) {
        //             return obj.duration + '天'
        //         }
        //     },
        // ]
        //时间轴图表中，如果不设置，只有行边框，区分上下的任务，设置之后带有列的边框，整个时间轴变成格子状。
        gantt.config.show_task_cells = true

        //是否显示依赖连线
        gantt.config.show_links = true;

        //设置x轴日期
        gantt.config.scale_unit = 'day'
        // 设置步长
        gantt.config.step = 1
        // 设置右侧显示日期格式
        // gantt.config.date_scale = '%M' + '%d' + '日' +  '(星期' + '%D' + ')'
        gantt.config.date_scale = '%m' + '-' + '%d'

        // 设置甘特图时间的起始结束时间，并允许显示超过时间刻度任务
        gantt.config.show_tasks_outside_timescale = true

        //当task的长度改变时，自动调整图表坐标轴区间用于适配task的长度
        gantt.config.fit_tasks = true
        // 在时间线上增加一行显示星期
        // 合并到date_scale，添加自定义多行的时候添加week只生效一行
        // Other Gantt chart configurations


        // 改写为自定义函数定义
        // gantt.config.subscales = [
        //     { unit:"day",  step:1, date:"星期"+"%D" },
        // ]


        gantt.config.subscales = [
            {
                unit: 'day',
                step: 1,
                date: function (date) {
                    const dateFormat = gantt.date.date_to_str('%M%d');
                    const dayOfWeek = date.getDay(); // 获取一周中的日期（0 表示周日，1 表示周一，以此类推）
                    // let subtitleText = '星期' + ['日', '一', '二', '三', '四', '五', '六'][dayOfWeek] + '<br/>' + dateFormat(date) + '日';
                    let subtitleText = ['日', '一', '二', '三', '四', '五', '六'][dayOfWeek] + '<br/>' + dateFormat(date) + '日';

                    // 根据日期判断是否是周六或周日，然后添加相应的 CSS 类
                    if (dayOfWeek === 6) { // 6 表示周六
                        subtitleText = '<div class="weekend">' + subtitleText + '</div>';
                    } else if (dayOfWeek === 0) { // 0 表示周日
                        subtitleText = '<div class="weekend">' + subtitleText + '</div>';
                    }

                    return subtitleText;
                },
            },
        ];


        // 添加自定义的列必须添加
        gantt.locale.labels["section_flag"] = "任务开启状态";

        gantt.config.lightbox.sections = [
            { name: "description", height: 38, map_to: "text", type: "textarea", focus: true },
            {
                name: "flag", height: 22, map_to: "flag", type: "select", options: [
                    { key: 1, label: "开启",value:1 },
                    { key: 0, label: "关闭",value:0 },
                ]
            },
            { name: "time", height: 36, type: "duration", map_to: "auto" },
        ];

        // 设置右侧列宽度
        gantt.config.min_column_width = 46;
        // 任务栏 + 甘特图 表头的高度
        // gantt.config.scale_height = 46;
        //时间轴图表中，任务条形图的高度
        gantt.config.task_height = 36
        //时间轴图表中，甘特图的高度
        gantt.config.row_height = 46
        //从后端过来的数据格式化
        gantt.config.xml_date = '%Y-%m-%d'
        // gantt.config.xml_date = "%Y-%m-%d %H:%i";

        //任务条显示内容
        gantt.templates.task_text = function (start, end, task) {
            return task.text + '(' + task.duration + '天)'
        }
        // gantt内置弹出框的内容 头部自定义
        gantt.templates.lightbox_header = function (start_date, end_date, task) {
            return `<b>${task.text}</b>`
        };

        // 添加右侧任务栏类名
        // gantt.templates.grid_row_class = function (start_date, end_date, item) {
        //     if (item.progress == 0.01) return "wait_task";
        // };

        // 添加左侧侧任务栏类名
        // gantt.templates.task_row_class = function (start_date, end_date, item) {
        //     if (item.progress == 0.01) return "wait_task";
        // };

        //悬浮
        // eslint-disable-next-line
        gantt.templates.tooltip_text = function (start, end, task) {
            //return "<b>任务名称:</b> "+task.text+"<br/><b>时长:</b> " + task.duration+"<br/><b>说明:</b>" +task.toolTipsTxt;
            return task.text && '<span style=\'font-size: 14px\'>' + task.text + '</span>'
        }
        //任务栏周末亮色
        gantt.templates.scale_cell_class = function (date) {
            if (date.getDay() == 0 || date.getDay() == 6) {
                return "weekend";
            }
        };

        gantt.templates.subscales_cell_class = function (date) {
            if (date.getDay() == 0 || date.getDay() == 6) {
                return "weekend";
            }
        };

        gantt.templates.timeline_cell_class = function (item, date) {
            if (date.getDay() == 0 || date.getDay() == 6) {
                return "weekend"
            }
        };


        gantt.templates.task_class = function (start, end, task) {
            if (task.flag == 0) {
                return "task_wait";
            }
        };

        // 监听任务新增事件
        gantt.attachEvent("onAfterTaskAdd", function (id, item) {
            console.log(id)
            console.log(item)
            const postData = {
                id: item.id,
                parent: parseInt(item.parent),
                text: item.text,
                progress: 0,
                start_date: formatDate(new Date(item.start_date)),
                end_date: formatDate(new Date(item.end_date)),
                duration: item.duration,
                flag: 1,
            }
            console.log(postData)

            taskAdd(postData).then(res => {
                  if(res.code == 200 && res.msg != ''){
                    Message.warning(res.msg);
                } 
            })
        });

        // 监听设置任务的最小进度
        gantt.attachEvent("onBeforeTaskUpdate", function (id, task) {
            if (task.progress < 0.01) {
                task.progress = 0.01; // 将进度设置为0.1
            }
            return true; // 返回true以允许任务更新，或返回false以禁止更新
        });


        // 监听任务修改事件
        gantt.attachEvent("onAfterTaskUpdate", function (id, item) {
            const postData = {
                id: item.id,
                parent: parseInt(item.parent),
                text: item.text,
                progress: item.progress,
                start_date: formatDate(new Date(item.start_date)),
                end_date: formatDate(new Date(item.end_date)),
                duration: item.duration,
                flag: parseInt(item.flag),
            }
          
            taskEdit(postData).then(res => {
                if(res.code == 200 && res.msg != ''){
                    Message.warning(res.msg);
                } else {
                    taskList().then(res => {
                        let data = res.data
                        data = data.map(item => {
                            return {
                                ...item,
                                sortTime: new Date(item.start_date).getTime()
                            }
                        }).sort((a, b) => a.sortTime - b.sortTime)

                        _this.tasks.data = data;
                        gantt.parse(_thisthis.tasks)
                    })
                }
            })
        });


        // 监听任务删除事件 onAfterTaskDelete onBeforeTaskDelete
        gantt.attachEvent("onAfterTaskDelete", function (id) {
            taskDel({ id }).then(res => {
                  if(res.code == 200 && res.msg != ''){
                    Message.warning(res.msg);
                } 
            })
        });


        // links 新增
        gantt.attachEvent("onLinkCreated", function (link) {
            if (getStroage('links')) {
                const localTask = getStroage('links');
                localTask.push(link)
                setStroage('links', localTask)
            } else {
                setStroage('links', [].concat(link))
            }
            return true;
        });

        // links 修改
        gantt.attachEvent("onAfterLinkUpdate", function (link) {
            console.log(link)
            return true;
        });

        // links 删除
        gantt.attachEvent("onAfterLinkDelete", function (id) {
            if (getStroage('links')) {
                const localTask = getStroage('links');
                const index = localTask.findIndex(linksItem => linksItem.id === id);
                localTask.splice(index, 1)
                setStroage('links', localTask)
            }
            return true;
        });

        
        
        // 初始化
        gantt.init(this.$refs.gantt);

        setTimeout(() => {
            gantt.showDate(new Date());
        }, 500); // 调整延迟时间可能需要根据实际情况

        taskList().then(res => {
            let data = res.data
            data = data.map(item => {
                return {
                    ...item,
                    sortTime: new Date(item.start_date).getTime()
                }
            }).sort((a, b) => a.sortTime - b.sortTime)

            this.tasks.data = data;
            gantt.parse(this.tasks)
        })

        // const role = window.localStorage.getItem('role');

        // 获取用户权限
        // setTimeout(() => {
        //    const element = document.querySelector('.gantt_grid_scale > .gantt_grid_head_add');
        //    if (role != 'admin') {
        //        element.style.display = 'none';
        //    }
        // }, 500)
    }
}

// 参考文章 https://www.inte.net/news/276765.html
</script>
<style lang="scss">
.container {
    height: 900px;
}

.gantt_scale_line {
    border-top: 0;
}

.weekend {
    /* z-index: 100; */
    background: #d9e1d9 !important;
}

.gantt_selected .weekend {
    background: #f7eb91;
}

.gantt_task_content {
    text-align: left;
    padding-left: 10px;
}

.task_wait {
    background: #ccc;
    border: 0;
}

.header_container {
    position: relative;
    width: 100%;
    height: 48px;
    display: flex;
    /* 使用 Flex 布局 */
    align-items: center;
    /* 垂直居中对齐 */
    padding: 10px 20px;

    .header_right {
        position: absolute;
        right: 28px;
        top: 50%;
        transform: translateY(-50%);
    }
}

// .gantt_container{
//     max-height:calc(100vh - 52px) !important;
//     overflow-y: auto !important;
// }
.gantt_layout_cell .gantt_hor_scroll {
    position: fixed !important;
    bottom: 5px !important;
}

.wait_task  {
    background-color: #ccc;
}

// 任务选中阴影颜色
.gantt_task_line.gantt_selected{
    box-shadow: 0 0 5px rgba(0,0,0,0.3);
}

</style>
  